package com.sky.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.mapper.ReportMapper;
import com.sky.mapper.WorkSpaceMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkSpaceService;
import com.sky.vo.*;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

@Service
public class ReportServiceImpl implements ReportService {


    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WorkSpaceService workSpaceService;


    /**
     * 营业额统计接口
     * @param begin
     * @param end
     * @return
     */
    public TurnoverReportVO turnoverStatistics(String begin, String end) {

        TurnoverReportVO vo = new TurnoverReportVO();


        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        LocalDate beginTime = LocalDate.parse(begin, formatter);
        LocalDate endTime = LocalDate.parse(end, formatter);

        List<Orders> ordersList = reportMapper.turnoverStatistics(beginTime,endTime.plusDays(1));

        Map map = new HashMap();

        LocalDate now = beginTime;
        while(!now.isAfter(endTime)) {
            BigDecimal amount = BigDecimal.valueOf(0);
            for (Orders orders : ordersList) {
                LocalDate time = orders.getCheckoutTime().toLocalDate();
                if (time.equals(now))
                {
                    BigDecimal ordersAmount = orders.getAmount();
                    amount = amount.add(ordersAmount);
                }
            }
            map.put(now.format(formatter), amount);
           now = now.plusDays(1);
        }
        StringBuilder dateList = new StringBuilder();
        StringBuilder amount = new StringBuilder();
        map.forEach((key,value)->{
            dateList.append(key+",");
            String price = value.toString();
            amount.append(price+",");
        });
        vo.setDateList(dateList.toString());
        vo.setTurnoverList(amount.toString());
        return vo;
    }

    /**
     * 统计用户
     * @param beginStr
     * @param endStr
     * @return
     */
    public UserReportVO userStatistics(String beginStr, String endStr) {

        LocalDate begin = LocalDate.parse(beginStr);
        LocalDate end   = LocalDate.parse(endStr);

        UserReportVO userReportVO = new UserReportVO();
        LocalDate now = begin;

        List<User> userList =  reportMapper.userStatistics(begin,end);

        StringBuilder dateList = new StringBuilder();
        StringBuilder newUserList = new StringBuilder();
        StringBuilder totalUserList = new StringBuilder();


        Integer totalUser = 0;
        while(!now.isAfter(end)) {
            Integer newUser = 0;
            for (User user : userList) {
                if(user.getCreateTime().toLocalDate().equals(now))
                {
                    newUser++;
                    totalUser++;
                }
            }
            dateList.append(now.toString()+",");
            newUserList.append(newUser.toString()+",");
            totalUserList.append(totalUser.toString()+",");

            now = now.plusDays(1);
        }

        userReportVO.setDateList(dateList.toString());
        userReportVO.setNewUserList(newUserList.toString());
        userReportVO.setTotalUserList(totalUserList.toString());


        return userReportVO;
    }

    /**
     * 订单统计
     * @param beginStr
     * @param endStr
     * @return
     */
    public OrderReportVO ordersStatistics(String beginStr, String endStr) {
        LocalDate begin = LocalDate.parse(beginStr);
        LocalDate end   = LocalDate.parse(endStr);
        OrderReportVO orderReportVO = new OrderReportVO();

        List<Orders> ordersList =  reportMapper.ordersStatistics(begin,end);

        LocalDate now = begin;
        Integer totalOrderCount = 0;
        Integer validOrderCount = 0;
        StringBuilder dateList = new StringBuilder();
        StringBuilder orderCountList = new StringBuilder();
        StringBuilder validOrderCountList = new StringBuilder();

        while(!now.isAfter(end)) {
                Integer todayTodayOrderCount = 0;
                Integer todayValidOrderCount = 0;
            for (Orders orders : ordersList) {
                if(orders.getOrderTime().toLocalDate().equals(now))
                {
                    if(orders.getStatus() == Orders.COMPLETED)
                    {
                        todayValidOrderCount++;
                        validOrderCount++;
                    }
                    todayTodayOrderCount++;
                    totalOrderCount++;
                }
                dateList.append(now.toString()+",");
                orderCountList.append(todayTodayOrderCount+",");
                validOrderCountList.append(todayValidOrderCount+",");
            }
            now = now.plusDays(1);
        }

        orderReportVO.setDateList(dateList.toString());
        orderReportVO.setOrderCountList(orderCountList.toString());
        orderReportVO.setValidOrderCountList(validOrderCountList.toString());
        orderReportVO.setTotalOrderCount(totalOrderCount);
        orderReportVO.setValidOrderCount(validOrderCount);
        BigDecimal rate = BigDecimal.valueOf(validOrderCount.doubleValue() / totalOrderCount.doubleValue());
        rate.setScale(2, BigDecimal.ROUND_HALF_UP);
        orderReportVO.setOrderCompletionRate(rate.doubleValue());

        return orderReportVO;
    }

    /**
     * 查询销量top10
     * @param beginStr
     * @param endStr
     * @return
     */
    public SalesTop10ReportVO salesTop10(String beginStr, String endStr) {
        LocalDate begin = LocalDate.parse(beginStr);
        LocalDate end   = LocalDate.parse(endStr);
        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();

        List<GoodsSalesDTO> goodsSalesDTOList =  reportMapper.salesTop10(begin,end);
        Map<String,Integer> map = new HashMap<>();
        for (GoodsSalesDTO goodsSalesDTO : goodsSalesDTOList) {
            Integer existedInteger = map.putIfAbsent(goodsSalesDTO.getName(), goodsSalesDTO.getNumber());
            if(existedInteger != null)
            {
                //键存在
                Integer number = goodsSalesDTO.getNumber();
                map.compute(goodsSalesDTO.getName(),(k,v)->v+number);
            }
        }

        StringBuilder nameList = new StringBuilder();
        StringBuilder numberList = new StringBuilder();

        map.forEach((k,v)->{
            nameList.append(k+",");
            numberList.append(v.toString()+",");
        });

        salesTop10ReportVO.setNameList(nameList.toString());
        salesTop10ReportVO.setNumberList(numberList.toString());

        return salesTop10ReportVO;
    }

    /**
     * 导出报表
     * @param response
     */
    public void exportBusiness(HttpServletResponse response) {
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end   = LocalDate.now().minusDays(1);

        BusinessDataVO businessDataVO = workSpaceService.getBusinessData(LocalDateTime.of(begin,LocalTime.MIN),LocalDateTime.of(end,LocalTime.MAX));

        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");

        try {
            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue("时间" + begin + "至" + end);
            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());

            XSSFRow row1 = sheet.getRow(4);
            row1.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row1.getCell(4).setCellValue(businessDataVO.getUnitPrice());

            for (int i = 0;i<30;i++)
            {
                LocalDate date  = begin.plusDays(i);
                BusinessDataVO businessData = workSpaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                row = sheet.getRow(7 + i);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
            }



            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            excel.close();
            outputStream.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}
